package cn.siriusbot.rpc.client;

import cn.siriusbot.rpc.*;
import cn.siriusbot.rpc.context.AbstractRpcContext;
import cn.siriusbot.rpc.entity.RpcNativeBody;
import cn.siriusbot.siriuspro.error.MsgException;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 基础的rpc客户端
 */
public class BasicsSiriusBotRpcClient extends AbstractRpcContext implements SiriusBotRpcClient, RpcContext, SiriusLoggerTransmit {

    protected SiriusLogger log  = new PrintLog();

    public BasicsSiriusBotRpcClient() {
    }

    public BasicsSiriusBotRpcClient(SiriusLogger log) {
        this.log = log;
    }

    /**
     * 处理器
     */
    RpcProcessor processor;

    private String getName(String name) {
        try {
            return name.substring(name.lastIndexOf(".") + 1);
        } catch (Throwable e) {
            return name;
        }
    }


    /**
     * 构建代理的Rpc对象
     *
     * @param clazz 被代理的接口
     * @return 请求对象
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> T buildApi(Class<T> clazz) {
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, (proxy, method, args) -> {
            if (processor == null) {
                throw new MsgException(500, "找不到RPC处理器!");
            }
            final RpcNativeBody body = new RpcNativeBody();
            body.setApiName(getName(clazz.getName()));
            body.setApi(proxy);
            body.setMethod(method);
            body.setParam(args);
            body.setReturnType(method.getReturnType());
            return processor.getResult(this, body);
        });
    }

    /**
     * 设置一个请求处理器
     *
     * @param processor 处理器
     */
    @Override
    public void setProcessor(RpcProcessor processor) {
        this.processor = processor;
    }

    /**
     * 寻找api的类
     *
     * @param apiName api名称
     * @return api对象
     */
    @Override
    protected Object findApiClass(String apiName) {
        throw new RuntimeException("RPC客户端不支持的操作!");
    }

    /**
     * 寻找api执行的方法
     *
     * @param apiObj api对象
     * @param method api方法名称
     * @return 方法对象
     */
    @Override
    protected Method findApiMethod(Object apiObj, String method) {
        throw new RuntimeException("RPC客户端不支持的操作!");
    }

    @Override
    public SiriusLogger getLog() {
        return this.log;
    }

    @Override
    public void setLog(SiriusLogger logger) {
        throw new RuntimeException("不支持的操作!");
    }
}
